package cn.schoolwow.quickdao.module.database.dml.instance.flow.insert.get;

import cn.schoolwow.quickdao.domain.QuickDAOConfig;
import cn.schoolwow.quickdao.domain.entity.Entity;
import cn.schoolwow.quickdao.domain.entity.Property;
import cn.schoolwow.quickdao.module.database.parent.domain.ResultSetConsumer;
import cn.schoolwow.quickdao.module.database.parent.flow.executor.ExecuteQueryConnectionFlow;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.util.domain.query.instance.QueryInstance;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class GetUniqueKeyValueListFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        Object[] instances = (Object[]) flowContext.checkData("instances");

        setStatement(flowContext);
        flowContext.putTemporaryData("uniqueKeyValueList", new ArrayList<>());
        for(int i=0;i<instances.length;i++){
            flowContext.putTemporaryData("instance", instances[i]);
            setParameters(flowContext);
            executeStatement(flowContext);
            flowContext.removeData("instance");
        }
    }

    @Override
    public String name() {
        return "根据唯一约束字段查询记录字段值";
    }

    private void setStatement(FlowContext flowContext){
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);
        Entity entity = (Entity) flowContext.checkData("entity");
        List<Property> uniquePropertyList = flowContext.checkData("uniquePropertyList", List.class);

        StringBuilder sqlBuilder = new StringBuilder("select");
        for(Property uniqueProperty:uniquePropertyList){
            sqlBuilder.append(" " + quickDAOConfig.databaseContext.databaseProvider.escape(uniqueProperty.column) + ",");
        }
        sqlBuilder.deleteCharAt(sqlBuilder.length()-1);
        sqlBuilder.append(" from " + quickDAOConfig.databaseContext.databaseProvider.escape(entity.tableName) + " where");
        for(Property uniqueProperty:uniquePropertyList){
            sqlBuilder.append(" " + quickDAOConfig.databaseContext.databaseProvider.escape(uniqueProperty.column) + " = ? and");
        }
        sqlBuilder.delete(sqlBuilder.length()-4,sqlBuilder.length());
        flowContext.putTemporaryData("sql", sqlBuilder.toString());
    }

    private void setParameters(FlowContext flowContext){
        Object instance = flowContext.checkData("instance");
        List<Property> uniquePropertyList = flowContext.checkData("uniquePropertyList", List.class);

        List<Object> parameters = new ArrayList();
        for (Property uniqueProperty : uniquePropertyList) {
            Object value = QueryInstance.newQuery(instance)
                    .execute()
                    .getSingleFieldValue(uniqueProperty.name);
            if(null==value){
                throw new IllegalArgumentException("实例唯一字段不能为空!实体类:"+instance.getClass().getName()+",字段名:"+uniqueProperty.name);
            }
            parameters.add(value);
        }
        flowContext.putTemporaryData("parameters", parameters);
    }

    private void executeStatement(FlowContext flowContext){
        List<Property> uniquePropertyList = flowContext.checkData("uniquePropertyList", List.class);
        List<String> uniqueKeyValueList = (List<String>) flowContext.getData("uniqueKeyValueList");

        StringBuilder uniqueFieldNameValueBuilder = new StringBuilder();
        flowContext.startFlow(new ExecuteQueryConnectionFlow())
                .putTemporaryData("name", "根据多个唯一约束字段查询记录字段值")
                .putReturnData("resultSetConsumer",new ResultSetConsumer() {
                    @Override
                    public void consumeResultSet(ResultSet resultSet) throws Exception {
                        while(resultSet.next()){
                            uniqueFieldNameValueBuilder.setLength(0);
                            for(Property uniqueProperty:uniquePropertyList){
                                uniqueFieldNameValueBuilder.append(resultSet.getString(uniqueProperty.column)+"|");
                            }
                            uniqueKeyValueList.add(uniqueFieldNameValueBuilder.toString());
                        }
                    }
                })
                .execute();
    }

}
